﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace 锁屏
{
    public class KeyBoardHook : HookBase
    {
        public KeyBoardHook()
        {
            // 底层键盘钩子
            idHook = 13;
        }
        public delegate int OnKeyDownHandel(KeyEventArgs keys);
        /// <summary>
        /// 键盘事件
        /// </summary>
        public event OnKeyDownHandel OnKeyBoardDownEvent;


        /// <summary>
        /// 键盘钩子处理函数
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        /// <remarks>此版本的键盘事件处理不是很好,还有待修正.</remarks>
        protected override int HookProcInstance(int nCode, Int32 wParam, IntPtr lParam)
        {
            int result = 0;
            KeyMSG m = (KeyMSG)Marshal.PtrToStructure(lParam, typeof(KeyMSG));
            if (CurPtr != IntPtr.Zero)
            {
                if (OnKeyBoardDownEvent != null)// || wParam == (int)WM_KEYBOARD.WM_KEYUP))
                {
                    KeyEventArgs e = new KeyEventArgs((Keys)m.vkCode);
                    result = OnKeyBoardDownEvent(e);
                }
            }
            if (result == 1)
            {
                return 1;
            }
            return CallNextHookEx(CurPtr, nCode, wParam, lParam);
        }

        /// <summary>
        /// 模拟键盘事件
        /// </summary>
        /// <param name="p"></param>
        /// <param name="intptr"></param>
        public void PressKey(Keys key, IntPtr intptr)
        {
            SendMessage(intptr, (int)WM_KEYBOARD.WM_KEYDOWN, (int)key, 0);
            SendMessage(intptr, (int)WM_KEYBOARD.WM_KEYUP, (int)key, 0);
        }

        /// <summary>
        /// 模拟键盘事件
        /// </summary>
        /// <param name="p"></param>
        /// <param name="intptr"></param>
        public void PressKey(uint type, int key, IntPtr intPtr)
        {
            if (intPtr != IntPtr.Zero)
            {
                SendMessage(intPtr, (uint)type, key, 0);
            }
        }
    }

    /// <summary>
    /// 键盘结构
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct KeyMSG
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    /// <summary>
    /// 键盘类型枚举
    /// </summary>
    public enum WM_KEYBOARD : int
    {
        /// <summary>
        /// 非系统按键按下
        /// </summary>
        WM_KEYDOWN = 0x100,
        /// <summary>
        /// 非系统按键释放
        /// </summary>
        WM_KEYUP = 0x101,
        /// <summary>
        /// 系统按键按下
        /// </summary>
        WM_SYSKEYDOWN = 0x104,
        /// <summary>
        /// 系统按键释放
        /// </summary>
        WM_SYSKEYUP = 0x105,

        WH_KEYBOARD_LL = 13,
    }
}
